/***************************************************************************
 *   Copyleft 2006-2007 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#include "./TorusManager.h"
#include "../Engine3D.h"
#include "../../Macros/Macros.h"
#include "../../resource.h"
#include "../../MemTracer/MemoryTracker.h"
/**************************************************************
* Constructors                                                *
***************************************************************/


/**************************************************************
* Operators                                                   *
***************************************************************/


/**************************************************************
* Other helpful functions                                     *
***************************************************************/
/*virtual*/ cVoid TorusManager::OnCommand(HWND hwnd, WPARAM wParam, LPARAM lParam, Engine3D* engine) {	
	cUShort cmd = LOWORD(wParam);
	
	if (mObject) {
		OnChangeFOV(engine, cmd);
		OnChangeParams(cmd);
		OnTransform(cmd);
	}
}

cVoid TorusManager::OnMouseMove(cPoint point, Engine3D* engine) {
	if (mLBDown) {
		::SetCursor(::LoadCursor(cNull, IDC_SIZEALL));
		mObject->Transform(
			Matrix4D::Translation(Point4D((cFloat)(point.x - mLBDownHit.x) * 0.42f, 
							(cFloat) -(point.y - mLBDownHit.y), 0.0f) * 1.0f), false);
		mLBDownHit = point;
	} else if (mRBDown) {
		::SetCursor(::LoadCursor(cNull, IDC_SIZENS));
		mObject->Transform(Matrix4D::Scaling(1.0f + (point.y - mRBDownHit.y) / 150.0f));
		mRBDownHit = point;
	}
}

cVoid TorusManager::OnLeftMouseUp(cPoint point, Engine3D* engine) {
	InputManager::OnLeftMouseUp(point, engine);
	::SetCursor(::LoadCursor(cNull, IDC_ARROW));
}

cVoid TorusManager::OnRightMouseUp(cPoint point, Engine3D* engine) {
	InputManager::OnRightMouseUp(point, engine);
	::SetCursor(::LoadCursor(cNull, IDC_ARROW));
}

cVoid TorusManager::OnTransform(cUShort cmd) {
	switch(cmd) {
		case ID_ROTTXA:
			mObject->Transform(Matrix4D::RotationX(-5.0f));
			break;
		case ID_ROTTXQ:
			mObject->Transform(Matrix4D::RotationX(5.0f));
			break;
		case ID_ROTTYS:
			mObject->Transform(Matrix4D::RotationY(-5.0f));
			break;
		case ID_ROTTYW:
			mObject->Transform(Matrix4D::RotationY(5.0f));
			break;
		case ID_ROTTZD:
			mObject->Transform(Matrix4D::RotationZ(-5.0f));
			break;
		case ID_ROTTZE:
			mObject->Transform(Matrix4D::RotationZ(5.0f));
			break;
		case ID_TRANSIZ:
			mObject->Transform(Matrix4D::Translation(Point4D(0.0f, 0.0f, 10.0f)), false);
			break;
		case ID_TRANSDZ:
			mObject->Transform(Matrix4D::Translation(Point4D(0.0f, 0.0f, -10.0f)), false);
			break;
		default:
			break;
	}
}

cVoid TorusManager::OnChangeParams(cUShort cmd) {
	Torus *oldTorus = (Torus*) mObject;

	switch(cmd) {
		case ID_INCV:
			oldTorus->Update(oldTorus->GetInternalRadius(), 
				oldTorus->GetExternalRadius(), oldTorus->GetU(), oldTorus->GetV() + 1);
			break;
		case ID_DECV:
			oldTorus->Update(oldTorus->GetInternalRadius(), 
				oldTorus->GetExternalRadius(), oldTorus->GetU(), oldTorus->GetV() - 1);
			break;
		case ID_INCU:
			oldTorus->Update(oldTorus->GetInternalRadius(), 
				oldTorus->GetExternalRadius(), oldTorus->GetU() + 1, oldTorus->GetV());
			break;
		case ID_DECU:
			oldTorus->Update(oldTorus->GetInternalRadius(), 
				oldTorus->GetExternalRadius(), oldTorus->GetU() - 1, oldTorus->GetV());
			break;
		case ID_INCER:
			oldTorus->Update(oldTorus->GetInternalRadius(), 
				oldTorus->GetExternalRadius() + 0.5f, oldTorus->GetU(), oldTorus->GetV());
			break;
		case ID_DECER:
			oldTorus->Update(oldTorus->GetInternalRadius(), 
				oldTorus->GetExternalRadius() - 0.5f, oldTorus->GetU(), oldTorus->GetV());
			break;
		case ID_INCIR:
			oldTorus->Update(oldTorus->GetInternalRadius() + 0.5f, 
				oldTorus->GetExternalRadius(), oldTorus->GetU(), oldTorus->GetV());
			break;
		case ID_DECIR:
			oldTorus->Update(oldTorus->GetInternalRadius() - 0.5f, 
				oldTorus->GetExternalRadius(), oldTorus->GetU(), oldTorus->GetV());
			break;
		default:
			break;
	}
}

cVoid TorusManager::OnChangeFOV(Engine3D* engine, cUShort cmd) {
	switch(cmd) {
		case ID_PERSI:
			engine->ChangeFOV(10.0f);
			break;
		case ID_PERSD:
			engine->ChangeFOV(-10.0f);
			break;
		default:
			break;
	}
}